﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ViewMaker.Core.ViewModels;
using System.Windows.Controls.Primitives;
using ViewMaker.Core.Wpf;
using System.Diagnostics;
using System.Windows.Markup;
using System.Windows.Threading;

namespace ViewMaker.Core.Views
{
    /// <summary>
    /// ViewLayoutView.xaml の相互作用ロジック
    /// </summary>
    public partial class ViewLayoutView : UserControl
    {
        public ViewLayoutViewModel ViewModel { get; set; }

        internal Window OwnerWindow { get { return Window.GetWindow(this); } }

        public ViewLayoutView()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(ViewLayoutView_Loaded);
            this.AddHandler(TreeViewItem.SelectedEvent, new RoutedEventHandler(OnTreeViewItemSelected));
        }

        /// <summary>
        /// LoadedのタイミングでViewModelと親ウインドウのイベントをワイヤーする
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ViewLayoutView_Loaded(object sender, RoutedEventArgs e)
        {
            ViewModel = (ViewLayoutViewModel)OwnerWindow.DataContext;
            ViewModel.ViewCommandNotified += new EventHandler<ViewCommandEventArgs>(ViewModel_ViewCommandNotified);
            ViewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ViewModel_PropertyChanged);
            OwnerWindow.Closing += new System.ComponentModel.CancelEventHandler(OwnerWindow_Closing);
        }

        /// <summary>
        /// ユーザーから閉じられた場合でもHideで一旦隠す
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OwnerWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (this.IsVisible)this.ViewModel.Hide();
            if (!this.ViewModel.Closing) e.Cancel = true;
        }

        /// <summary>
        /// 画面の再表示・隠す制御
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ViewModel_ViewCommandNotified(object sender, ViewCommandEventArgs e)
        {
            switch (e.Command)
            {
                case "Activate":
                    OwnerWindow.Activate();
                    break;
                case "Hide":
                    OwnerWindow.Hide();
                    break;
            }
        }

        #region TreeView操作

        void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "CurrentItem" && ViewModel.CurrentItem != null)
            {
                var tvi = FindTreeViewItem(ViewModel.CurrentItem);
                if (tvi != null) tvi.IsSelected = true;
            }
        }

        private TreeViewItem FindTreeViewItem(ViewLayoutItem item)
        {
            TreeViewItem tvi = null;
            if (item.Parent == null)
            {
                tvi = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(item);
            }
            else
            {
                var parent = FindTreeViewItem(item.Parent);
                if (parent != null) tvi = (TreeViewItem)parent.ItemContainerGenerator.ContainerFromItem(item);
            }
            if (tvi != null)
            {
                tvi.IsExpanded = true;
                tvi.UpdateLayout();
            }
            return tvi;
        }

        private void TreeViewItem_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (sender is TreeViewItem)
            {
                var item = sender as TreeViewItem;
                item.IsSelected = true;
                e.Handled = true;
            }
        }

        private void MenuItemModify_Click(object sender, RoutedEventArgs e)
        {
            var item = e.Source as MenuItem;
            if (item != null) this.ViewModel.ModifyControlCommand.Execute(item.CommandParameter);
        }
        private void MenuItemAddItem_Click(object sender, RoutedEventArgs e)
        {
            var item = e.Source as MenuItem;
            if (item != null) this.ViewModel.GenerateItemCommand.Execute(item.CommandParameter);
        }

        private void MenuItemAddControl_Click(object sender, RoutedEventArgs e)
        {
            var item = e.Source as MenuItem;
            if (item != null) this.ViewModel.AddControlCommand.Execute(item.CommandParameter);
        }

        private void treeView_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                if (this.ViewModel.CurrentItem == null) return;
                this.ViewModel.RemoveItemCommand.Execute(null);
            }
            if (this.ViewModel.CurrentItem != null && (e.KeyboardDevice.IsKeyDown(Key.LeftShift) || e.KeyboardDevice.IsKeyDown(Key.RightShift)))
            {
                if (e.KeyboardDevice.IsKeyDown(Key.Down))
                {
                    this.ViewModel.DownCommand.Execute(null);
                    e.Handled = true;
                }
                else if (e.KeyboardDevice.IsKeyDown(Key.Up))
                {
                    this.ViewModel.UpCommand.Execute(null);
                    e.Handled = true;
                }
                else if (e.KeyboardDevice.IsKeyDown(Key.Right))
                {
                    this.ViewModel.RightCommand.Execute(null);
                    e.Handled = true;
                }
                else if (e.KeyboardDevice.IsKeyDown(Key.Left))
                {
                    this.ViewModel.LeftCommand.Execute(null);
                    e.Handled = true;
                }
            }
        }

        private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            ViewModel.CurrentItem = e.NewValue as ViewLayoutItem;

        }

        private void OnTreeViewItemSelected(object sender, RoutedEventArgs e)
        {
            TreeViewItem item = e.OriginalSource as TreeViewItem;
            if (item != null) item.BringIntoView();
        }
        #endregion

    }
}
